<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>



<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="hevea 1.08">
<LINK rel="stylesheet" type="text/css" href="embroot.css">
<TITLE>
Communication via Queues
</TITLE>
</HEAD>
<BODY >
<A HREF="embroot031.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="embroot026.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="embroot033.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2 CLASS="section"><A NAME="htoc54">6.6</A>&nbsp;&nbsp;Communication via Queues</H2><UL>
<LI><A HREF="embroot032.html#toc24">Queue Data Handlers</A>
<LI><A HREF="embroot032.html#toc25">Synchronous Queues</A>
<LI><A HREF="embroot032.html#toc26">Asynchronous Queues</A>
<LI><A HREF="embroot032.html#toc27">Reusable Queue Names</A>
<LI><A HREF="embroot032.html#toc28">Translating the Queue Names</A>
</UL>

Queues should be used to set up long-term I/O links between ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> and
Tcl. An example would be the main output from an application that is to be
displayed by a Tcl window. Streams of bytes can be sent along the queue
from one side to the other: on one side, data is written to the queue; and
when the queue is flushed, the data is sent to the other side, which can
now read the data. The data can either be sent as normal strings (where
each byte represents a character) using the normal I/O calls, or they can
be in EXDR format, in which case both sides need to read and write using
EXDR.<BR>
<BR>
On the Tcl side, the queue is seen as a Tcl I/O
channel. On the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side, a queue is
seen as an ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> I/O stream, which has a unique (numeric) ID, the
stream number, and has a user supplied symbolic
name. These all refer to the same queue. Queues are created using the symbolic names, and the Tcl side
maintains tables of the correspondence between Tcl channel names, symbolic
names and stream numbers. The built-in Tcl I/O commands accepts the Tcl
channel name for operating on the queue, and for 
compatibility with the embedding interface, many of the Tcl remote
interface commands refer to the queue using the stream number. The
interface provides commands to inter-convert the various names so that the
right name can be used for a particular command.<BR>
<BR>
There are two types of queues: 
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<B>synchronous</B><DD CLASS="dd-description"> These queues are unidirectional,
i.e. either for sending data from ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> to Tcl (from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>), or
from Tcl to ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> (to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>). 
These streams are synchronous because the interface ensures that the
sending and receiving of data across the queue are synchronised. This is
achieved by transferring control between
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> and Tcl in a coroutine-like manner to ensure that data that is
sent from one side is processed on the other. <BR>
<BR>
These queues are designed to be compatible with the queues
created via ec_queue_create of the embedded interface 
(see section&nbsp;<A HREF="embroot021.html#ecqueueconnect">5.5</A>). Their actual implementations are
different, in that the queues in the embedded case are memory queues and
the synchronous queue use socket connections. The interface tries to
minimise the difference by buffering where
possible at either ends of the socket connection. However, there is an overhead for doing
this, and not all differences can be hidden. This is discussed in more detail in section&nbsp;<A HREF="embroot035.html#remotediff">6.9</A>.
<BR>
<BR>
<DT CLASS="dt-description"><B>asynchronous</B><DD CLASS="dd-description"> These are bi-directional &ndash;
data can be sent both ways. Sending or receiving data on these queues does
not necessarily transfer control between ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> and
Tcl. In particular, it is not possible to request data from the other side
if the queue is empty: such an operation would simply block. 
This is because such queues map
directly to the socket connections with no buffering, and there is no concept of a socket
being empty. Generally, it is up to the programmer to co-ordinate the
transfer and processing of the data. <BR>
<BR>
They have no direct
equivalent in the embedding Tcl interface, but some uses of the embedding
Tcl interface queues, such as writing data from one side without a
corresponding reader on the other side, are better approximated by the
asynchronous queues than the synchronous queues. They can also be more
efficient in that there is no buffering of the data is performed by the
interface. </DL>
<A NAME="toc24"></A>
<H3 CLASS="subsection"><A NAME="htoc55">6.6.1</A>&nbsp;&nbsp;Queue Data Handlers</H3>
<A NAME="remotehandles"></A>
The processing of data on queues (synchronous and to some extent
asynchronous) can be performed via <I>handlers</I>. A handler is a piece of
code (a procedure in Tcl, a goal in ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>) whose execution is
data-driven: it is invoked to deal
with the transfer of data on a queue on their respective sides. <BR>
<BR>
In ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>, the handler goal is invoked using the events mechanism. That
 is, an event is raised, and the event handler goal associated with the event
 (see <A HREF="../bips/kernel/event/set_event_handler-2.html"><B>set_event_handler/2</B></A><A NAME="@default129"></A>) is then executed when ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> has control. <BR>
<BR>
A handler can be called under two situations:
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<B>Data consumer</B><DD CLASS="dd-description"> To consume data that has been sent over from the other
side. Here, the other side has sent data over the queue, invoking the handler.
The handler is expected to read the data off the queue and process it.
An example of a data consumer handler is a Tcl handler which is invoked
when the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side sends data that is intended to be displayed on a Tcl
window. The handler would be
invoked to read the data off the queue and display it on the window. <BR>
<BR>
<DT CLASS="dt-description"><B>Data provider</B><DD CLASS="dd-description"> To provide data that has been requested by the other side. In this
 case, the handler is expected to generate the data and write the data onto
 the queue, and send it to the other side. For example, on the Tcl side, a
 Tcl handler might be invoked to ask for inputs from the user via the GUI.
 Note that these data providers can only exist for the synchronous
 queues.</DL>
For each queue and for a particular direction of data flow, a
handler can be defined on either the Tcl or the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side, but not
both. The handler either consumes or provides data as described above. The
reason that handlers cannot be defined on both sides 
is that this avoids possible infinite loop of alternately
triggering the data provider and the data consumer.<BR>
<BR>
<A NAME="toc25"></A>
<H3 CLASS="subsection"><A NAME="htoc56">6.6.2</A>&nbsp;&nbsp;Synchronous Queues</H3>
These queues can be created on the Tcl side. This is done with
the <B>ec_queue_create</B> command from within Tcl code:
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<A NAME="@default130"></A><B>ec_queue_create <I>eclipse_stream_name mode ?command? ?event?</I></B><DD CLASS="dd-description"><BR>
Creates a synchronous queue between Tcl and ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> sides. On
 the Tcl side, a Tcl channel is created. On the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side, the 
 queue would be given the symbolic name <I>eclipse_stream_name</I>. 
 The <I>mode</I> argument indicates the direction of the queue, and
 can either be fromec or toec<SUP><A NAME="text7" HREF="embroot026.html#note7">4</A></SUP>.
 The procedure returns a channel identifier for use in commands
 like <B>puts</B>, <B>read</B>, <B>ec_read_exdr</B>,
 <B>ec_write_exdr</B> or <B>close</B>. The optional arguments <I>command</I> and <I>event</I> specifies the data handler for the
 queue: <I>command</I> is the name
 of the Tcl
 procedure for handling the data, with its user defined arguments. 
 <I>event</I> is the name of the event that will be
 raised on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side (see the section&nbsp;<A HREF="#remotehandles">6.6.1</A>
 for more details). As a handler can only be defined for one side,
 either <I>event</I> or <I>command</I> should be undefined
 (<CODE>{}</CODE>). 
<DT CLASS="dt-description"><A NAME="@default131"></A><B>ec_queue_close <I>eclipse_stream_name</I></B><DD CLASS="dd-description"><BR>
	Closes the (synchronous or asynchronous) queue with the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> name of <I>	ec_stream_name</I>. The queue is closed on both the Tcl and ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
	sides, and bookkeeping information for the queue is removed. </DL>
It is strongly recommended that the queues should be used for long-term I/O
connections between the two sides, and so the queues should not be created
and closed on a short-term basis. For quick interchange of data, it is
recommended that the user use the <B>ec_rpc</B> mechanism.<BR>
<BR>

<H4 CLASS="subsubsection">Handlers for a Synchronous From-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> Queue</H4>

<H5 CLASS="paragraph">Tcl Handler for From-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> Queue</H5>
For a from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue, the Tcl handler <I>command</I> would be a
data consumer. This handler is initiated when
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side initially has control and flushes
the queue (by calling <A HREF="../bips/kernel/iostream/flush-1.html"><B>flush/1</B></A><A NAME="@default132"></A>). With a Tcl handler defined,
control is transferred to the Tcl
side, where <I>command</I> is invoked to consume the data. When the
handler finishes, control is returned to the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side. The general
sequence of actions are:<BR>
<BR>
<BR>

<DIV CLASS="center">
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD ALIGN=left NOWRAP>ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side</TD>
<TD ALIGN=left NOWRAP>Tcl side</TD>
</TR>
<TR><TD ALIGN=left NOWRAP>6.5cmWrites to the from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue</TD>
<TD ALIGN=left NOWRAP>&nbsp;</TD>
</TR>
<TR><TD ALIGN=left NOWRAP>6.5cmFlush the from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue</TD>
<TD ALIGN=left NOWRAP>&nbsp;</TD>
</TR>
<TR><TD ALIGN=left NOWRAP>&nbsp;</TD>
<TD ALIGN=left NOWRAP>6.5cmHandler invoked to handle data on the from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue</TD>
</TR>
<TR><TD ALIGN=left NOWRAP>6.5cmECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> returns from flush, and continue executing the following code</TD>
<TD ALIGN=left NOWRAP>&nbsp;</TD>
</TR></TABLE> 
</DIV>
<BR>
<BR>
<BR>
The Tcl handler is specified by <I>command</I> in <B>ec_queue_create</B>. <I>command</I> includes the name of the Tcl procedure to
invoke, and any user defined arguments. When the handler is invoked, two
additional arguments are appended:
the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream number for the queue, and the number
of bytes that has been sent on the queue. This command should read the data
off the queue and process it. The following predefined Tcl
data consumer handlers are provided:
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<A NAME="@default133"></A><B>ec_stream_to_window_sync <I>tag text_widget stream_nr length</I></B><DD CLASS="dd-description"><BR>
Read <I>length</I> bytes from the specified queue and insert the data
 at the end of the existing <I>text_widget</I>, using <I>tag</I> as the tag
 for the text. If this is invoked as a handler for a from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
 queue, <I>length</I> and <I>stream_nr</I> would be supplied when
 the handler is invoked.<BR>
<BR>
<DT CLASS="dt-description"><A NAME="@default134"></A><B>ec_stream_output_popup <I>label_text stream_nr length</I></B><DD CLASS="dd-description"><BR>
Pops up a window displaying the <I>label_text</I>,
 a text field displaying the contents of the specified queue stream,
 and an ok-button for closing. The data is read as normal
 strings. This is the default Tcl fromec handler that will be called
 if <B>ec_create_queue</B> did not define one.</DL>
 

<H5 CLASS="paragraph">An example from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue with Tcl handler</H5>
To create the queue on the Tcl side with a Tcl handler:
<PRE CLASS="verbatim">
Tcl code :  ec_queue_create myqueue fromec {ec_stream_to_window_sync red textwin} {}
</PRE>
Note that the last <CODE>{}</CODE> specifies that there is no ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
handler. This is the actual default for this argument, so it could be
missed out. After creating the queue, it can be used on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
side. The programmer can write to the queue, and to send the data to the
Tcl side, the queue should be flushed:
<PRE CLASS="verbatim">
ECLiPSe code :
   ...
   write(myqueue, hello),
   flush(myqueue),
   ...
</PRE>
When the queue is flushed as shown above, then control is handed over to
Tcl, and the Tcl handler, in this case <B>ec_stream_to_window_sync</B>,
would be invoked. This reads the data on the queue (hello, and anything
else that has been written since the last flush), and puts it into the text
widget textwin, with the tag red. The procedure is also called with the
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream number for the queue and the number of bytes sent as extra
arguments. The textwin widget and the tag red must
be defined already in the Tcl program (presumably `red' means printing the
text in red colour); if no tag is desired, <CODE>{}</CODE> can be used. <BR>
<BR>
The procedure <B>ec_stream_to_window_sync</B> is predefined in the
interface, but here is a slightly
simplified version of it:
<PRE CLASS="verbatim">
proc ec_stream_to_window_sync {Tag Window Stream Length} {

    set channel [ec_streamnum_to_channel $Stream]
    set data [read $channel $Length]

    $Window insert end $data $Tag
    $Window see end
}
</PRE>

<H5 CLASS="paragraph">ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> Handler for From-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> Queue</H5>
Currently, the Tcl remote interface does not support ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> handlers
(which will be a data provider) for from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queues. Thus, the <I>event</I> argument for <B>ec_queue_create</B> is currently a dummy argument
that is ignored. The available alternative is to use <B>ec_rpc</B> to obtain
the required information: instead of reading from a from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>queue, an
ec_rpc should be called with argument(s) left to be filled in by the
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side with the required data. <BR>
<BR>

<H4 CLASS="subsubsection">Handlers for a Synchronous To-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> Queue</H4>

<H5 CLASS="paragraph">Tcl Handler for a To-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> Queue</H5>
<A NAME="toeclipse-tclhandler"></A>
For a to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue, the Tcl handler <I>command</I> defined in <B>ec_queue_create</B> would be a data
producer. This handler is initiated when ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side has control, and
reads from the to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue, which is initially empty. With a Tcl
handler defined, control is transferred to the Tcl side, where <I>command</I> is invoked to provide the data. The handler should write the
data to the queue, and call the Tcl remote interface command <B>ec_flush</B>
to send the data to ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side. When the handler finishes,
control is returned to the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side, and the read operation is
performed to read the now available data. The general sequence of actions are:<BR>
<BR>
<BR>

<DIV CLASS="center">
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD ALIGN=left NOWRAP>ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side</TD>
<TD ALIGN=left NOWRAP>Tcl side</TD>
</TR>
<TR><TD ALIGN=left NOWRAP>6.5cmReads an empty to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue</TD>
<TD ALIGN=left NOWRAP>&nbsp;</TD>
</TR>
<TR><TD ALIGN=left NOWRAP>&nbsp;</TD>
<TD ALIGN=left NOWRAP>6.5cmHandler invoked to supply data to the
 to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue. The data is written to the queue and flushed
 with <B>ec_flush</B></TD>
</TR>
<TR><TD ALIGN=left NOWRAP>6.5cmECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> returns from the initial read operation, reading
 the data supplied by the Tcl handler, and continue execution the following code</TD>
<TD ALIGN=left NOWRAP>&nbsp;</TD>
</TR></TABLE>
</DIV>
<BR>
<BR>
<BR>
The Tcl remote interface command <B>ec_flush</B>, instead of the standard
Tcl <B>flush</B> command, should be used to flush a
queue so that the data would be transferred and processed on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
side. <B>ec_flush</B> should be used both inside the Tcl data provider
handler, and also to invoke an ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> data consumer handler (see the
next section).
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<A NAME="@default135"></A><B>ec_flush <I>eclipse_streamnum ?nbytes?</I></B><DD CLASS="dd-description"><BR>
If the Tcl side has control, flushes the (synchronous or asynchronous) queue
 with the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream number <I>eclipse_streamnum</I> and hands over
 control briefly to ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> to read the data. Control is
 then returned to Tcl. <I>nbyte</I> is an optional argument that specifies the
 number of bytes being sent. If this argument is missing, the data sent
 must be a single EXDR term in the case of the synchronous queue. There
 is no restriction for the asynchronous queues, but it is the
 programmer's responsibility that the read operation does not block.
</DL>
Normally, data is written to the queue using standard Tcl output commands,
and the amount of data written is not known. However, the programmer may
have kept track of the number of bytes written inside the handler, and thus
know how many bytes will be sent. In this case, <B>ec_flush</B> can be
called with the number of bytes supplied as a parameter. It is the
programmer's responsibility to ensure that this information is accurate.
Without nbytes, the output is restricted to EXDR terms for synchronous
queues. The reason for this is because the data is sent through a socket
connection, and without knowing the amount of data, it is not possible in
general to know when the data ends, unless the data sent has implicit
boundaries, like an EXDR term.<BR>
<BR>
For the use of <B>ec_flush</B> inside a Tcl data provider handler, the
sequence of events that appears to the user is that the <B>ec_flush</B>
flushes the data, and the Tcl side then continues executing Tcl code
until the handler's execution is finished. Control is then returned to
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>, where the original read operation can now read the available
data. The actual sequence of event is slightly more complex for synchronous
queues: when <B>ec_flush</B> is invoked, control is actually transferred to ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>, and
the data flushed is then read into a buffer by ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>, which then
returns control to Tcl to continue the execution of the handler. When the
handler finally finishes, control returns to ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>, and the original
read operation reads the data from the buffer and continues. This extra
complexity should be transparent to the programmer except when the
intermediate ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> read to buffer does not complete (e.g. because
<I>nbytes</I> is greater than the actual amount of data sent). <BR>
<BR>
The Tcl handler is specified by <I>command</I> in <B>ec_queue_create</B>. <I>command</I> includes the name of the Tcl procedure to
invoke, and any user defined arguments. When the handler is invoked, an
additional argument is appended:
the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream number for the queue. This command should get the
data required, output it onto the queue, and call <B>ec_flush</B> to flush
the data to ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side. If the command does not flush data to
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>, ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> will print a warning and return control to Tcl side.<BR>
<BR>
The following predefined Tcl data producer
handler is provided:
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<A NAME="@default136"></A><B>ec_stream_input_popup <I>label_text stream_nr</I></B><DD CLASS="dd-description"><BR>
Pops up a window displaying the label_text, an input field
 and an ok-button. The text typed into the input field will
 be written into the specified queue stream <I>stream_nr</I>, which
 is the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream number for the queue. If this command is
 invoked as a handler for a to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue, <I>stream_nr</I>
 will be automatically appended by the interface. There should be no
 unflushed data already on the queue when this command is invoked.
</DL>

<H5 CLASS="paragraph">An example to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue with Tcl handler</H5>
To create the queue on the Tcl side with a Tcl-handler:
<PRE CLASS="verbatim">
Tcl code :  
ec_queue_create myqueue toec \
    {ec_stream_input_popup "Input for myqueue:"} {}
</PRE>
This associates the pre-defined Tcl data producer handler <B>ec_input_popup</B> with myqueue. The last <CODE>{}</CODE> specifies that there is no
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> handler and can be omitted as that is the default. This queue
can now be used on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side in a demand driven way, i.e.
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side can read from the queue:
<PRE CLASS="verbatim">
ECLiPSe code :

    ...
    read(myqueue, Data),
    ...
</PRE>
When the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side reads from myqueue, and the queue contains no data
on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side, then
control will be handed over to Tcl, and <B>ec_input_popup</B> 
invoked. This pops up a Tcl window, with the label &#8220;Input for myqueue:&#8221;
with a text entry widget, asking the user to supply the requested data. The
data is then sent back to the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side.<BR>
<BR>
Here is a slightly simplified version (there are no buttons)
of <B>ec_stream_input_popup</B>:
<PRE CLASS="verbatim">
set ec_stream_input_string {}

proc ec_stream_input_popup {Msg Stream} {
    global ec_stream_input_string

    toplevel .ec_stream_input_box
    label .ec_stream_input_box.prompt  -width 40 -text $Msg
    entry .ec_stream_input_box.input -bg white -width 40 \
        -textvariable ec_stream_input_string
    bind .ec_stream_input_box.input &lt;Return&gt; {destroy .ec_stream_input_box}

    ;# pack the popup window
    pack .ec_stream_input_box.prompt -side top -fill x
    pack .ec_stream_input_box.input -side top -fill x

    tkwait window .ec_stream_input_box
    puts -nonewline [ec_streamnum_to_channel $Stream] $ec_stream_input_string
    ;# flush the output to ECLiPSe with the length of the input
    ec_flush $Stream [string length $ec_stream_input_string]
}

</PRE>
Data is flushed to the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side using <B>ec_flush</B>. The <B>puts</B>
needs the Tcl channel name of the queue to write to, and this is provided
via the Tcl remote interface command <B>ec_streamnum_to_channel</B> (see
section&nbsp;<A HREF="#translate-remote-qnames">6.6.5</A>). <B>ec_flush</B> is called with two
arguments in this case, both the queue number (<I>Stream</I>), and the
length of the data that is sent. Note that this makes the assumption that
no other unflushed data has been written to the queue. <BR>
<BR>

<H5 CLASS="paragraph">ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> Handler for a To-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> Queue</H5>
For a to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue, the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> handler would be a data
consumer. This handler is initiated when Tcl initially has control, and
flushes data on a queue using <B>ec_flush</B>. Control is transferred to
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>, and if the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> handler is defined, this is invoked to
consume the data. When the handler returns, control is returned to Tcl,
which continues executing the code after the flush. The general sequence of
actions are:<BR>
<BR>
<BR>

<DIV CLASS="center">
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD ALIGN=left NOWRAP>ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side</TD>
<TD ALIGN=left NOWRAP>Tcl side</TD>
</TR>
<TR><TD ALIGN=left NOWRAP>	</TD>
<TD ALIGN=left NOWRAP>6.5cmOutputs data onto the to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue</TD>
</TR>
<TR><TD ALIGN=left NOWRAP>	</TD>
<TD ALIGN=left NOWRAP>6.5cmCalls <B>ec_flush</B> to send data to ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side</TD>
</TR>
<TR><TD ALIGN=left NOWRAP>6.5cmThe ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> handler associated with the queue is called to consume and
process the data</TD>
<TD ALIGN=left NOWRAP>&nbsp;</TD>
</TR>
<TR><TD ALIGN=left NOWRAP>	</TD>
<TD ALIGN=left NOWRAP>6.5cmExecution continues after the <B>ec_flush</B></TD>
</TR></TABLE>
</DIV>
<BR>
<BR>
<BR>
The ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> handler is specified by the <I>event</I> argument of <B>ec_queue_create</B>. This specifies an event that will be raised on the
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side when data is written to a previously empty queue. The
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side does not see this data, and the event not raised, until the
data is flushed by <B>ec_flush</B> and copied by ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> to its
buffer and, if the buffer was initially empty, the event would then be raised.<BR>
<BR>
The programmer should define the event handler associated with <I>event</I>.<BR>
<BR>

<H5 CLASS="paragraph">An example to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue with ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> handler</H5>
To create the queue on the Tcl side with an ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>-handler:
<PRE CLASS="verbatim">
Tcl code: 
    ec_queue_create myqueue toec {} remoteflush_myqueue
</PRE>
Note that the <CODE>{}</CODE> is needed to specify that there is no Tcl handler. 
It defines <CODE>remoteflush_myqueue</CODE> as the event that will be raised when
the queue is flushed by <B>ec_flush</B> on the Tcl side. <BR>
<BR>
The event handler needs to be defined on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side:
<PRE CLASS="verbatim">
ECLiPSe code:

:- set_event_handler(remoteflush_myqueue, read_myqueue/0).

...
read_myqueue :-
      read_exdr(myqueue, Data),
      process(Data).

</PRE>
This read handler assumes that the data is written using EXDR format. So on
the Tcl side, the data should be written using EXDR format:
<PRE CLASS="verbatim">
Tcl code:

     ...
     ec_write_exdr [ec_streamname_to_channel myqueue] $data
     ec_flush [ec_streamname_to_streamnum myqueue]
     ...
</PRE>
<A NAME="toc26"></A>
<H3 CLASS="subsection"><A NAME="htoc57">6.6.3</A>&nbsp;&nbsp;Asynchronous Queues</H3>
Asynchronous queues are created on the Tcl side using the Tcl command <B>ec_async_queue_create</B>:
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<A NAME="@default137"></A><B>ec_aysnc_queue_create <I>eclipse_stream_name ?mode?
?fromec_command? ?toec_event?</I></B><DD CLASS="dd-description"><BR>
	Creates a socket stream between ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> and Tcl with the name
	<I>eclipse_stream_name</I> on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side. The created
	stream is bidirectional, and can be written to or read from at both
	ends. The <I>mode</I> argument is for compatibility with the <I>	ec_aysnc_queue_create</I> command of the embedded interface only,
	and has no effect on the nature of the queue. The procedure
	returns a channel identifier for use in commands like <B>puts</B>,
	<B>read</B>, <B>ec_read_exdr</B>, <B>ec_write_exdr</B> or <B>	close</B>. Unlike the synchronous queues, only data consumer handlers
	can be defined: if a <I>fromec_command</I> argument is provided,
	this command is set as the Tcl data consumer handler to be called
	when data arrives on the Tcl end of the socket. If <I>toec_event</I>
	is given, it specifies the event that will be raised on the
	ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side when data is flushed by <I>ec_flush</I> on the Tcl
	side. 
<DT CLASS="dt-description"><A NAME="@default138"></A><B>ec_queue_close <I>eclipse_stream_name</I></B><DD CLASS="dd-description"><BR>
	Closes the (synchronous or asynchronous) queue with the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
	name of <I>	ec_stream_name</I>. The queue is closed on both the Tcl and ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
	sides, and bookkeeping information for the queue is removed. </DL>
Asynchronous queues are bi-directional queues which allows data transfer
between ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> and Tcl sides without transfer of control. 
In the case where a Tcl data consumer
handler is defined in <I>fromec_command</I>, which is invoked on the Tcl
side when the queue is flushed on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side, the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side
will carry on execution while the handler is invoked on the Tcl side. <BR>
<BR>
These queues are designed to allow for more efficient transfer of data
between ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> and Tcl than the synchronous queues. <BR>
<BR>
For data transfer from
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> to Tcl, the intended use is that a Tcl data consumer handler
 would be invoked as the data becomes available on
the Tcl side, after being flushed from the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side. 
Note that control is not handed over to Tcl side in this case:
the Tcl handler is
invoked and executed on the Tcl side while ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side still has control, with the
restriction that the Tcl handler is unable to issue <B>ec_rpc</B>
goals because ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side still retains control. Another difference
with the synchronous from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue is that the handler would read
from the queue in non-blocking mode, i.e. it will read whatever data is
available on the queue at the Tcl side and never wait for more data. 
If more data become
available, the handler would be invoked again. The following Tcl handler is
pre-defined for the asynchronous queue for handling from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> data:
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<A NAME="@default139"></A><B>ec_stream_to_window <I>tag text_widget stream_nr length</I></B><DD CLASS="dd-description"><BR>
Inserts all the current contents of the specified queue 
 at the end of the existing <I>text_widget</I>, using <I>tag</I> as
 the tag for the text. </DL>
For data transfer from Tcl to ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>, 
the queue can be used either asynchronously or synchronously. 
If the
queue is used asynchronously, then the standard Tcl command <B>flush</B>
should be used to flush the queue. There would not be any transfer of
control, and so there would not be an
immediate corresponding read on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side. In fact, no handler
would be invoked automatically on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side, even when control is
transferred. 
Output and flush
operations do not block on the Tcl side, as the Tcl side of the queue is
put into non-blocking mode, so that the data is buffered and the operations
carried out when they will not block. It is the programmer's responsibility
to write and call the code to read the data from the queue on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side when
the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side is given control.<BR>
<BR>
This asynchronous use to send data to ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> should be useful when
the queue is used as an auxiliary data
channel, where the main data is sent either via <B>ec_rpc</B> or another
queue. The desired effect is that data can be sent on the auxiliary channel
without triggering processing on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side until it is told to do
so on the main data channel, which would be handled synchronously. <BR>
<BR>
To use the queue synchronously for
to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> data, <B>ec_flush</B> should be used to flush the queue on the
Tcl side. 
With <B>ec_flush</B>, control will be handed over to the
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side to process the data: the goal associated with the event <I>toec_event</I> is
executed, and this goal should read the data from the queue. 
Unlike the synchronous to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
queues, the data is not buffered, and the handler goal is called every time
<B>ec_flush</B> is invoked, rather than only when the queue is empty. This
should normally not make any difference, as the handler should empty all
the contents of a queue each time it is invoked.<BR>
<BR>
The goal is called with two optional arguments: the first argument is the
event name, the second argument is the `culprit' of the form
<CODE>rem_flushio(Queue,Len)</CODE>, indicating that this event is caused by a
remote flush, where Queue is the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream number,
and Len is the number of bytes sent (this is supplied by <B>ec_flush</B>, if
<B>ec_flush</B> does not supply a length, then Len is the atom
<CODE>unknown</CODE>.<BR>
<BR>

<H4 CLASS="subsubsection">Examples for asynchronous queue</H4>

<H5 CLASS="paragraph">Using the queue asynchronously: to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP></H5>
An example of using an asynchronous queue asynchronously to send data to
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> is in the tracer for TkECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> development tools. Here the trace line is
printed on a synchronous from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue, and handled by a Tcl data
consumer handler which prints the trace line and waits for the user to type
in a debugger command. This debugger command is sent to the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>-side
using an asynchronous queue, which is read by the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side when it
returns. Here is a much simplified version of the code:
<PRE CLASS="verbatim">
Tcl code:
    ...
    ec_queue_create debug_traceline fromec handle_trace_line
    ec_async_queue_create debug_input toec ;# no handlers
    ...
</PRE>
During the initialisation of the development tools, the Tcl code creates
the from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> queue where the trace-line information is sent
(<CODE>debug_traceline</CODE>), and the asynchronous queue (used only in a
to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> direction) for sending the debugger commands to ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
(creep, leap, skip etc.). Note that as this queue is used asynchronously,
there are no handlers associated with it.<BR>
<BR>
On the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side, when a goal with a spy-point is executed, this
raises an event that calls the predicate <CODE>trace_line_handler/2</CODE> which 
should output the trace-line, and wait for a debug command, process the
command, and carry on:
<PRE CLASS="verbatim">
trace_line_handler(_, Current) :-
        % Current contains information on the current execution state
        % from this a trace line Traceline (a string) can be created
        make_current_traceline(Current, Traceline),
        % send the traceline to Tcl side
        write_exdr(debug_traceline, Traceline),
        flush(debug_traceline), 
        % flush will return when the Tcl handler has finished
        read_exdr(debug_input, Cmd),
        % read the command from debug_input and process it
        interpret_command(Cmd, Current).
</PRE>
The trace-line handler is called with the second argument set to a
structure that contain information on the current execution state
(<CODE>Current</CODE>), from this, a trace-line (the debug port name, depth, goal
being traced etc.) can be constructed: <CODE>Traceline</CODE> is the string that
should be printed, e.g.
<PRE CLASS="verbatim">
  (1) 1 CALL  append([1, 2, 3], [], L)
</PRE>This is sent as an EXDR term to the Tcl side using the synchronous
queue <CODE>debug_traceline</CODE>. When <CODE>flush/1</CODE> is
called, control is handed over to the Tcl to handle the data, and the
Tcl data consumer handler <B>handle_trace_line</B> is invoked:
<PRE CLASS="verbatim">
proc handle_trace_line {stream length} {
 global tkecl

        $ec_tracer.trace.text insert end \
             [ec_read_exdr [ec_streamnum_to_channel $stream]]
        configure_tracer_buttons active

        ;# wait for a tracer command button to be pressed...
        tkwait variable tkecl(tracercommand)
 configure_tracer_buttons disabled
        ec_write_exdr [ec_streamname_to_channel debug_input] \
             $tkecl(tracercommand)
        flush [ec_streamname_to_channel debug_input]
}
</PRE>
As this is invoked as a handler, the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream number (<I>stream</I>) and number of bytes sent (<I>length</I>) are appended as
arguments. Note that as the trace-line is written as an EXDR term, the <I>length</I> information is actually not needed. What the handler does is
simply read the trace-line as an EXDR term, and placing the resulting
string onto the tracer text window <CODE>$ec_tracer_trace.text</CODE>. Next, <B>configure_tracer_buttons active</B> is called. This code is not shown, but
what it does is to enable the buttons for the debugger commands so that the
user can press them. There are buttons for the debugger commands such as
`leap', `creep' etc. When one of this button is pressed, the global
variable <CODE>tkecl(tracercommand)</CODE> is set to the corresponding command,
and the handler continues its execution beyond the <B>tkwait</B>. The
buttons are disabled, the command sent to ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side on the
<CODE>debug_input</CODE> queue using <B>flush</B>. This is the asynchronous
sending of data on the asynchronous queue:
control is <I>not</I> handed
over to ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> to process this command. Instead, the execution on the
Tcl side carries on (and happens to finish immediately after the <B>flush</B>. Control is then returned to the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side as the Tcl handler
has finished, and the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side continues execution after the
<CODE>flush(debug_traceline)</CODE> goal. Next, <CODE>debug_input</CODE> is read for
the tracer command, and this command is acted on.<BR>
<BR>

<H5 CLASS="paragraph">Using the queue synchronously: to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP></H5>
If the Tcl remote interface command <B>ec_stream_input_popup</B> (see section&nbsp;<A HREF="#toeclipse-tclhandler">6.6.2</A>) is used to
send data to the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>-side (in section&nbsp;<A HREF="#toeclipse-tclhandler">6.6.2</A>,
the command was initiated by a read operation on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side; here
the command is invoked directly when Tcl side has control), then the
following is a possible ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> handler:
<PRE CLASS="verbatim">
Tcl code:

;# create the asynchronous queue, with
;#  from-ECLiPSe Tcl consumer handler: data_to_window 
;#  to-ECLiPSe ECLiPSe handler event:  flush_myqueue
ec_async_queue_create myqueue {data_to_window textwin} flush_myqueue

...
;# get input for the queue and send to ECLiPSe side
ec_stream_input_popup "Data:" [ec_channel_to_streamnum myqueue]
...

ECLiPSe code:

:- set_event_handler(flush_myqueue, read_remote_data/2).

% Len is known when ec_stream_input_popup is used to send data
read_remote_data(_Event, rem_flushio(Queue,Len)) :-
 read_string(Queue, "", Len, Data), 
 process(Data).

</PRE>
The ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> code defines <CODE>read_remote_data/2</CODE> as the handler for
to-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> data sent with <B>ec_flush</B> on the Tcl side. This handler
is called when control is handed over to ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side to read the
data. Both the two optional arguments are used in this handler. The second
argument supplies the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream number for the queue and the length
of data written. As the data is
sent by explicitly calling <B>ec_stream_input_popup</B>, the length of the
data sent is known, so <CODE>read_string/4</CODE> can be used to read the exact amount of
data. In the asynchronous queue, it is generally the programmer's
responsibility to ensure that the read will not block.<BR>
<BR>

<H5 CLASS="paragraph">Using the queue asynchronously: from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP></H5>
The example <CODE>ec_async_queue_create</CODE> also defines a Tcl data consumer
handler to handle data sent on the from-ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> direction, with a user
defined argument of the text window that the data will be sent to. Here is
a simple procedure which reads the data on the queue and places it on the
text window specified:
<PRE CLASS="verbatim">
Tcl code:

proc data_to_window {Window Stream} {
    set channel [ec_streamnum_to_channel $Stream]

    $Window insert end [read $channel]
}

</PRE>
The <I>Stream</I> argument is appended by the interface when the handler is
invoked, and is the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream number of the queue. The procedure
simply reads the data from the corresponding Tcl channel and display the
data on <I>Window</I>, the text window specified by the programmer.<BR>
<BR>
<A NAME="toc27"></A>
<H3 CLASS="subsection"><A NAME="htoc58">6.6.4</A>&nbsp;&nbsp;Reusable Queue Names</H3>
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream names are global in scope, so using fixed queues names
like `myqueue' might cause name conflicts with other modules, if the
programmer intend the remote Tcl code to be usable with other ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> code.
One way to avoid name clashes is to dynamically composing queue names using
the name of the control connection:
<PRE CLASS="verbatim">
Tcl code:
        append queue_name [ec_control_name] myqueue
        ec_queue_create $queue_name fromec {ec_stream_output_popup red textwin}
</PRE>
The user specified name `myqueue' is appended to the control name of the
remote connection to give a unique queue name. On the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side, 
the code will also need to use the dynamic name:
<PRE CLASS="verbatim">
        :- local variable(remote_control). 

        ...
        % code fragment to remember the control name
        remote_connect(Addr, Control, _),
        setval(remote_control, Control), 
        ...

        ...
        % code fragment to use the queue
        getval(remote_control, Control),
        concat_atom([Control, myqueue], QName),
        ...
        write(QName, hello), flush(QName),
        ...

</PRE>
<A NAME="toc28"></A>
<H3 CLASS="subsection"><A NAME="htoc59">6.6.5</A>&nbsp;&nbsp;Translating the Queue Names</H3>
<A NAME="translate-remote-qnames"></A>
The remote queues connecting ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> and Tcl are given different names
on the two sides. The remote Tcl interface
keeps track of the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> names for the queues on the Tcl side. On the
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side, the queue has a stream number, as well as possibly several
symbolic aliases. The interface only keeps track of one symbolic name &ndash;
the one that is supplied in <I>ec_queue_connect</I> and <I>ec_async_queue_create</I>. If the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream number was supplied in
these commands, then the stream number is also considered the symbolic name
for the queue as well. The Tcl interface provides several commands to convert the names
from one form to another:
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<A NAME="@default140"></A><B>ec_streamname_to_channel <I>eclipse_name</I></B><DD CLASS="dd-description"><BR>
	Returns the Tcl channel name for the remote queue with the
	symbolic name <I>eclipse_name</I>. 
<DT CLASS="dt-description"><A NAME="@default141"></A><B>ec_streamnum_to_channel <I>eclipse_stream_number</I></B><DD CLASS="dd-description"><BR>
	Returns the Tcl channel name for the remote queue with the
	ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream number <I>eclipse_stream_number</I>.
<DT CLASS="dt-description"><A NAME="@default142"></A><B>
	ec_channel_to_streamnum <I>channel</I></B><DD CLASS="dd-description"><BR>
	Returns the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream number for the remote queue with the
	Tcl channel name <I>channel</I>.
<DT CLASS="dt-description"><A NAME="@default143"></A><B>ec_streamname_to_streamnum <I>eclipse_name</I></B><DD CLASS="dd-description"><BR>
	Returns the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stream number for the remote queue with the
	symbolic name <I>eclipse_name</I>.
<DT CLASS="dt-description"><A NAME="@default144"></A><B>ec_stream_nr <I>eclipse_name</I></B><DD CLASS="dd-description"><BR>
	This is an alias for <B>ec_streamname_to_streamnum</B> for
	compatibility with embedded interface.
</DL>
<HR>
<A HREF="embroot031.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="embroot026.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="embroot033.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
